package com.hq.pool;

import com.hq.instantiation.MyThread;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池的顶级接口 Executor
 * ExecutorService extends Executor 2个实现子类 AbstractExecutorService  ScheduledExecutorService
 * ThreadPoolExecutor extends AbstractExecutorService(常用)
 * ScheduledThreadPoolExecutor entends ThreadPoolExecutor  implements ScheduledExecutorService（带定时）
 * <p>
 * java为了创建线程池方便点 提供了工具类 Executors(e个 rai k特丝) 能创建四大线程池
 * 1、newCachedThreadPool 创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。
 * 2、newFixedThreadPool 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
 * 3、newScheduledThreadPool 创建一个定长线程池，支持定时及周期性任务执行。
 * 4、newSingleThreadExecutor 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
 */
@SuppressWarnings("all")
public class ExecutorPoolDemo {
    public static void main1(String[] args) {
        //1、通过 Executors 创建一个行程池（固定数量的线程池）
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Executors.newScheduledThreadPool(10);
        Executors.newSingleThreadExecutor();
        //2、从线程池中的 一个线程  并执行一个Runnable实例
        executorService.execute(new MyThread());
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Runnable runnable = () -> {
            System.out.println(Thread.currentThread().getName());
        };
        Runnable runnable1 = () -> {
            System.out.println(Thread.currentThread().getName());
        };
        executorService.submit(runnable);
        executorService.submit(runnable1);
    }

    @Bean("taskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
         /*
        设置最大线程数
         当前线程数=maxPoolSize，且任务缓冲队列已满时，线程池会拒绝处理任务而抛出异常。
         当前线程数>=corePoolSize，且任务缓冲队列已满时。线程池会创建新线程来处理任务。
         */
        //设置核心线程数  最大线程数
        threadPool.setCorePoolSize(16);
        threadPool.setMaxPoolSize(200);
        //线程池所使用的缓冲队列
        threadPool.setQueueCapacity(50);
        //等待任务在关机时完成--表明等待所有线程执行完
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        //线程名称前缀
        threadPool.setThreadNamePrefix("MyAsync-");
        //任务拒绝处理器
        threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //设置allowCoreThreadTimeout=true（默认false）时，核心线程会超时关闭。
        //threadPool.setAllowCoreThreadTimeOut(true);
        ////线程空闲时间达到keepAliveTime时，线程会退出，直到线程数量=corePoolSize
        threadPool.setKeepAliveSeconds(60);
        // 初始化线程
        threadPool.initialize();
        return threadPool;
    }
}
